package com.echo.neocommunity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.echo.neocommunity.mapper.LoginTicketMapper;
import com.echo.neocommunity.mapper.UserMapper;
import com.echo.neocommunity.pojo.LoginTicket;
import com.echo.neocommunity.pojo.User;
import com.echo.neocommunity.service.UserService;
import com.echo.neocommunity.utils.CommunityConstant;
import com.echo.neocommunity.utils.CommunityUtil;
import com.echo.neocommunity.utils.MailClient;
import com.echo.neocommunity.utils.RedisKeyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MailClient mailClient;

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private LoginTicketMapper loginTicketMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${community.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;


    public User getUserById(@Param("id") int id){
        User user = getCache(id);
        if(user==null){
           user = initCache(id);
        }
        return user;
    }


    public Map<String,Object> register(User user){
        Map<String,Object> map=new HashMap<>();
        if(user==null){
            throw new IllegalArgumentException("参数不能为空！");
        }
        if(StringUtils.isBlank(user.getUsername())){
            map.put("usernameMsg","用户名不能为空");
        }
        if(StringUtils.isBlank(user.getPassword())){
            map.put("passwordMsg","密码不能为空");
        }
        if(StringUtils.isBlank(user.getEmail())){
            map.put("emailMsg","邮箱不能为空");
        }
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",user.getUsername());
        User u = userMapper.selectOne(queryWrapper);
        if(u!=null){
            map.put("usernameMsg","用户名已经存在");
        }
        queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("email",user.getEmail());
        u=userMapper.selectOne(queryWrapper);
        if(u!=null){
            map.put("emailMsg","该邮箱已经被注册！");
        }
        if(map.isEmpty()){
            user.setSalt(CommunityUtil.generateUUID().substring(0,5));
            user.setPassword(CommunityUtil.md5(user.getPassword()+user.getSalt()));
            user.setType(0);
            user.setStatus(0);
            user.setActivationCode(CommunityUtil.generateUUID());
            user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png",new Random().nextInt(1000)));
            user.setCreateTime(new Date());
            userMapper.insert(user);
            int id = userMapper.getUserIdByUserName(user.getUsername());
            user.setId(id);
            Context context=new Context();
            context.setVariable("email",user.getEmail());
            String url=domain+contextPath+"/activation/"+user.getId()+"/"+user.getActivationCode();
            context.setVariable("url",url);
            String content=templateEngine.process("/mail/activation",context);
            mailClient.sendMail(user.getEmail(),"牛客网账号激活",content);
        }
        return map;
    }

    @Override
    public int activation(int userId,String userCode) {
        User user = userMapper.selectById(userId);
        if(user.getStatus()==1){
            return CommunityConstant.ACTIVATION_REPEAT;
        }else if(user.getActivationCode().equals(userCode)){
            user.setStatus(1);
            userMapper.updateById(user);
            clearCache(userId);
            return CommunityConstant.ACTIVATION_SUCCESS;
        }else{
            return CommunityConstant.ACTIVATION_FAIL;
        }
    }

    @Override
    public Map<String, Object> login(String username, String password, int expiredSeconds) {
        Map<String, Object> map=new HashMap<>();
        if(username==null ||StringUtils.isEmpty(username)){
            map.put("usernameMsg","账号不能为空！");
            return map;
        }
        if(password==null ||StringUtils.isEmpty(password)){
            map.put("passwordMsg","密码不能为空！");
            return map;
        }
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",username);
        User user = userMapper.selectOne(queryWrapper);
        if(user==null){
            map.put("usernameMsg","账号不存在！");
            return map;
        }
        if(user.getStatus()==0){
            map.put("usernameMsg","该账号未激活，请先前往激活后登录！");
            return map;
        }
        String md5Password=CommunityUtil.md5(password+user.getSalt());
        if(!md5Password.equals(user.getPassword())){
            map.put("passwordMsg","密码不正确！");
            return map;
        }
        LoginTicket loginTicket=new LoginTicket();
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(CommunityUtil.generateUUID());
        loginTicket.setStatus(0);
        loginTicket.setExpired(new Date(System.currentTimeMillis()+1000*expiredSeconds));
//        loginTicketMapper.insert(loginTicket);
        redisTemplate.opsForValue().set(RedisKeyUtils.getTicketKey(loginTicket.getTicket()),loginTicket);
        map.put("ticket",loginTicket.getTicket());
        return map;
    }

    public void loginOut(String ticket){
//        QueryWrapper<LoginTicket> queryWrapper=new QueryWrapper<>();
//        queryWrapper.eq("ticket",ticket);
//        LoginTicket loginTicket = loginTicketMapper.selectOne(queryWrapper);
//        loginTicket.setStatus(1);
//        loginTicketMapper.updateById(loginTicket);
        LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(RedisKeyUtils.getTicketKey(ticket));
        loginTicket.setStatus(1);
        redisTemplate.opsForValue().set(RedisKeyUtils.getTicketKey(ticket),loginTicket);
    }

    public LoginTicket getLoginTicketByTicket(@Param("ticket") String ticket){
//        QueryWrapper<LoginTicket> queryWrapper=new QueryWrapper<>();
//        queryWrapper.eq("ticket",ticket);
//        LoginTicket loginTicket = loginTicketMapper.selectOne(queryWrapper);
        LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(RedisKeyUtils.getTicketKey(ticket));
        return loginTicket;
    }

    public int updateUrlHeader(User user,String userHeaderUrl){
        user.setHeaderUrl(userHeaderUrl);
        clearCache(user.getId());
        return userMapper.updateById(user);
    }

    public int updateUserPassword(User user,String newPassword){
        newPassword=CommunityUtil.md5(newPassword+user.getSalt());
        user.setPassword(newPassword);
        clearCache(user.getId());
        return userMapper.updateById(user);
    }

    public User getCache(int userId){
        String userKey = RedisKeyUtils.getUserKey(userId);
        User o = (User) redisTemplate.opsForValue().get(userKey);
        return o;
    }

    public User initCache(int userId){
        User user=userMapper.selectById(userId);
        String userKey = RedisKeyUtils.getUserKey(userId);
        redisTemplate.opsForValue().set(userKey,user,3600, TimeUnit.SECONDS);
        return user;
    }

    public void clearCache(int userId){
        String userKey = RedisKeyUtils.getUserKey(userId);
        redisTemplate.delete(userKey);
    }


}
